/*
Pyxis 2.0
Copyright 2010-2011 Thomas W. Holtquist

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

using System;
using System.Collections;

using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Skewworks.Pyxis.EXT;
using Skewworks.Pyxis.Kernel;

namespace Skewworks.Pyxis.GUI.Controls
{

    [Serializable]
    public class Panel : Container
    {

        #region Variables

        private Color _bkg = Colors.LightGray;

        #endregion

        #region Constructors

        public Panel(int x, int y, int width, int height)
        {
            _x = x;
            _y = y;
            _w = width;
            _h = height;
        }

        public Panel(int x, int y, int width, int height, Color background)
        {
            _x = x;
            _y = y;
            _w = width;
            _h = height;
            _bkg = background;
        }

        #endregion

        #region Touch Invokes

        public override void TouchDown(object sender, point e)
        {
            if (!_visible) return;

            // Check controls
            Control myControl = null;
            for (int i = _children.Count - 1; i >= 0; i--)
            {
                myControl = (Control)_children[i];
                if (myControl.ScreenBounds.contains(e))
                {
                    myControl.TouchDown(this, e);
                    return;
                }
            }

            _mDown = true;
        }

        public override void TouchUp(object sender, point e)
        {
            if (!_visible) return;

            bool ignoreUp = false;
            bool ret = false;

            // Check controls
            try
            {
                Control myControl = null;
                for (int i = _children.Count - 1; i >= 0; i--)
                {
                    myControl = (Control)_children[i];
                    if (myControl.ScreenBounds.contains(e) && !ignoreUp)
                    {
                        myControl.TouchUp(this, e);
                        ret = true;
                        ignoreUp = true;
                    }
                    else if (myControl.PenDown)
                    {
                        myControl.TouchUp(this, e);
                    }
                }
            }
            catch (Exception)
            {
                // just move on
            }

            if (!ret && _mDown) OnTap(this, new point(e.X, e.Y - 22));
        }

        public override void TouchMove(object sender, point e)
        {
            // Check controls
            try
            {
                Control myControl = null;
                for (int i = _children.Count - 1; i >= 0; i--)
                {
                    myControl = (Control)_children[i];
                    myControl.TouchMove(sender, e);
                }
            }
            catch (Exception)
            {
                // just move on
            }
        }

        #endregion

        #region  Properties

        public Color Background
        {
            get { return _bkg; }
            set { _bkg = value; }
        }
        
        #endregion

        #region Internal Methods

        public override void SetOffset(Control sender, point e)
        {
            if (sender != _parent)
                throw new Exception("Only a parent can set a child's offset");
            _xOffset = e.X;
            _yOffset = e.Y;

            Control ctrl;
            for (int i = 0; i < _children.Count; i++)
            {
                ctrl = (Control)_children[i];
                ctrl.SetOffset(this, new point(Left, Top));
            }
        }

        #endregion

        #region GUI

        public override void Render(bool flush)
        {
            if (_parent == null || _parent.ScreenBuffer == null || !_visible || _suspend) return;

            // Set clipping region in case we're off parent somewhere (can happen w/ scroll)
            _parent.ScreenBuffer.SetClippingRectangle(_parent.Left, _parent.Top, _parent.Width, _parent.Height);

            _parent.ScreenBuffer.DrawRectangle(_bkg, 0, Left, Top, _w, _h, 0, 0, _bkg, 0, 0, _bkg, 0, 0, 256);

            for (int i = 0; i < _children.Count; i++)
            {
                Control ele = (Control)_children[i];
                ele.Render();
            }

            if (flush)
            {
                _parent.ScreenBuffer.Flush(Left, Top, _w, _h);
                _parent.ScreenBuffer.SetClippingRectangle(0, 0, AppearanceManager.ScreenWidth, AppearanceManager.ScreenHeight);
            }
        }

        #endregion

    }
}
